package cn.dgut.training.service.impl;

import cn.dgut.training.annotation.LoginUser;
import cn.dgut.training.controller.GoodsService;
import cn.dgut.training.controller.UserService;
import cn.dgut.training.dto.goods.CommentDTO;
import cn.dgut.training.dto.goods.CommentDTO;
import cn.dgut.training.dto.goods.GoodsAllDTO;
import cn.dgut.training.dto.goods.GoodsListDTO;
import cn.dgut.training.dto.goods.GoodsProductDTO;
import cn.dgut.training.entity.CommentCount;
import cn.dgut.training.entity.goods.*;
import cn.dgut.training.mapper.*;
import cn.dgut.training.service.IGoodsService;
import cn.dgut.training.vo.BaseVO;
import cn.dgut.training.vo.CommonResponse;
import cn.dgut.training.vo.goods.GoodsListVO;
import cn.dgut.training.vo.goods.GoodsProductVO;
import cn.dgut.training.vo.goods.GoodsSpecificationVO;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import net.bytebuddy.asm.Advice;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.*;


@Service
public class GoodsServiceImpl extends ServiceImpl<GoodsMapper, Goods> implements IGoodsService {

    @Resource
    private GoodsMapper goodsMapper;

    @Resource
    private GoodsSpecificationServiceImpl goodsSpecificationService;

    @Resource
    private GoodsSpecificationMapper goodsSpecificationMapper;

    @Resource
    private GoodsProductServiceImpl goodsProductService;

    @Resource
    private GoodsProductMapper goodsProductMapper;

    @Resource
    private CartServiceImpl cartService;

    @Resource
    private  CommentServiceImpl commentService;

    @Resource
    private CategoryMapper categoryMapper;

    @Resource
    private CartMapper cartMapper;

    @Resource
    private UserService userService;

    /**
     * 增加商品
     * @param goodsAllDTO
     * @return
     */
    @Transactional
    public CommonResponse add(GoodsAllDTO goodsAllDTO){

        //1.参数验证（分类/商品名是否存在）
        if(checkExistedByName(goodsAllDTO.getGoods().getName())){
            return CommonResponse.fail("商品名已经存在");
        }
        //2.插入商品表
        Goods goods=new Goods();
        BeanUtils.copyProperties(goodsAllDTO.getGoods(),goods);
        goods.setGallery(StringUtils.join(goodsAllDTO.getGoods().getGallery(),','));
        goods.setGoodsSn(UUID.randomUUID().toString().replace("-", "").toLowerCase());
        //2.1 遍历所有商品库存表的最低价赋值到retailPrice
        BigDecimal retailPrice=new BigDecimal(Integer.MAX_VALUE);
        for (GoodsProductDTO p:goodsAllDTO.getProducts()) {

            if(p.getPrice().compareTo(retailPrice)==-1){
                retailPrice=p.getPrice();
            }

        }
        goods.setRetailPrice(retailPrice);
        goodsMapper.insert(goods);

        //3.插入商品规格表

        for (GoodsSpecification s:goodsAllDTO.getSpecifications()) {
            s.setGoodsId(goods.getId());
            goodsSpecificationService.save(s);
        }

        //4.插入商品库存表

        for (GoodsProductDTO p:goodsAllDTO.getProducts()) {
            GoodsProduct goodsProduct=new GoodsProduct();
            BeanUtils.copyProperties(p,goodsProduct);
            goodsProduct.setSpecifications(StringUtils.join(p.getSpecifications(),','));
            goodsProduct.setGoodsId(goods.getId());
            goodsProductService.save(goodsProduct);
        }
        return CommonResponse.message();
    }

    public boolean checkExistedByName(String name){

        return goodsMapper.selectCount(new QueryWrapper<Goods>().lambda().eq(Goods::getName,name))!=0;
    }
    /**
     * 编辑商品
     *
     *  更新表操作
     *  1.goods表可以编辑字段；
     *  2.goods_specification表只能编辑pic_url字段，其他操作不支持；
     *  3.goods_product表只能编辑price, 和url字段，其他操作不支持；
     *
     * 涉及的其他业务
     *  1.购物车缓存了一些商品信息，因此需要及时更新。
     *  2.目前这些字段是goods_sn, goods_name, price, pic_url。
     *  3.但是订单里面的商品信息则是不会更新。
     *  4.如果订单是未支付订单，此时仍然以旧的价格支付。
     * @param goodsAllDTO
     * @return
     */
    @Transactional
    public CommonResponse edit(GoodsAllDTO goodsAllDTO){

        //1.更新商品表
        Goods goods=new Goods();
        BeanUtils.copyProperties(goodsAllDTO.getGoods(),goods);
        goods.setGallery(StringUtils.join(goodsAllDTO.getGoods().getGallery(),','));
        goodsMapper.updateById(goods);

        //2.转换
        List<GoodsProduct> goodsProducts=new ArrayList<>();

        for (GoodsProductDTO p:goodsAllDTO.getProducts()){
            GoodsProduct goodsProduct=new GoodsProduct();
            BeanUtils.copyProperties(p,goodsProduct);
            goodsProduct.setSpecifications(StringUtils.join(p.getSpecifications(),','));
            goodsProducts.add(goodsProduct);
        }
        //3.更新商品规格表和更新购物车的参数
        for (GoodsProduct p:goodsProducts) {
            goodsProductService.updateById(p);
            cartService.updateByGoodsProduct(p,goods);
        }
        return CommonResponse.success(goodsAllDTO);
    }

    /**
     * 删除商品
     * @param goods
     * @return
     */
    @Transactional
    public CommonResponse delete(Goods goods){

        //1.检测id是否为空，可放到controller层检测
        Long id=goods.getId();
        //2.级联删除
        goodsMapper.deleteById(id);
        goodsSpecificationService.removeById(id);
        goodsProductService.removeById(id);
        return CommonResponse.message();
    }

    /**
     * 分页展示所有商品
     * @param goodsListDTO
     * @return
     */
    public BaseVO listGoodsByPage(GoodsListDTO goodsListDTO){

        IPage page=new Page();
        BeanUtils.copyProperties(goodsListDTO,page);

        QueryWrapper queryWrapper=GoodsListDTO.getWrapper(goodsListDTO);

        IPage res=goodsMapper.selectPage(page,queryWrapper);

        //转换
        List<Goods> goods=res.getRecords();
        List<GoodsListVO> goodsListVOS=new ArrayList<>();
        for (Goods g:goods) {
            GoodsListVO temp=new GoodsListVO();
            BeanUtils.copyProperties(g,temp);
            String s=g.getGallery();
            temp.setGallery(s.split(","));
            goodsListVOS.add(temp);

        }

        res.setRecords(goodsListVOS);
        BaseVO baseVO=new BaseVO(res);

        return baseVO;
    }

    /**
     * 编辑的时候根据id查询单条记录
     * @param id
     * @return
     */
    public CommonResponse detail(Long id){

        //查询分类
        Integer[] categoryIds = new Integer[]{1,2,3};

        //查询三个表

        //1.商品
        Goods goods=goodsMapper.selectById(id);
        //转换
        GoodsListVO goodsListVO=new GoodsListVO();
        BeanUtils.copyProperties(goods,goodsListVO);
        String s=goods.getGallery();
        goodsListVO.setGallery(s.split(","));

        //2.规格
        QueryWrapper queryWrapper=new QueryWrapper();
        queryWrapper.eq("goods_id",id);
        Object[] specifications=goodsSpecificationMapper.selectList(queryWrapper).toArray();



        //3.产品
        List<GoodsProduct> goodsProducts=goodsProductMapper.selectList(queryWrapper);

        //转换
        GoodsProductVO[] goodsProductVOS=new GoodsProductVO[goodsProducts.size()];
        int index=0;

        for (GoodsProduct gp:goodsProducts) {

            GoodsProductVO temp=new GoodsProductVO();
            BeanUtils.copyProperties(gp,temp);
            String ss=gp.getSpecifications();
            temp.setSpecifications(ss.split(","));
            goodsProductVOS[index]=temp;
            index++;

        }

        Map<String, Object> data = new HashMap<>();
        data.put("goods", goodsListVO);
        data.put("specifications", specifications);
        data.put("products", goodsProductVOS);
        data.put("categoryIds", categoryIds);
        return CommonResponse.success(data);
    }

    /**
     * 查询是新品的商品
     * @return
     */
    public List<Goods> queryByNew(){

        return goodsMapper.selectList(new LambdaQueryWrapper<Goods>().eq(Goods::getIsNew,1)
                .orderByDesc(Goods::getAddTime).last("limit 6"));

    }

    /**
     * 查询是热门的商品
     * @return
     */
    public List<Goods> queryByHot(){

        return goodsMapper.selectList(new LambdaQueryWrapper<Goods>().eq(Goods::getIsHot,1)
                .orderByDesc(Goods::getAddTime).last("limit 6"));

    }

    /**
     * 商品详情—小程序端
     * @param userId
     * @param goodsId
     * @return
     */
    public CommonResponse getById(@LoginUser Long userId, Long goodsId){

        Map<String,Object> data=new HashMap<>();

        //商品信息
        Goods goods=goodsMapper.selectById(goodsId);
        GoodsListVO goodsListVO=new GoodsListVO();
        BeanUtils.copyProperties(goods,goodsListVO);
        String s=goods.getGallery();
        goodsListVO.setGallery(s.split(","));
        //商品规格
        List<GoodsSpecificationVO> goodsSpecificationVOS=getSpecification(goodsId);

        //商品规格对应的数量和价格
        List<GoodsProduct> goodsProducts=goodsProductMapper.selectList(
                new LambdaQueryWrapper<GoodsProduct>().eq(GoodsProduct::getGoodsId,goodsId));
        //评论
        List<Comment> comments=null;
        data.put("comment",comments);
        //用户收藏

        data.put("info", goodsListVO);
        //购物车数量
        Integer number=cartMapper.selectCount(new LambdaQueryWrapper<Cart>().eq(Cart::getUserId,userId));
        data.put("cartGoodsCount",number);
        //用户是否已经收藏,1收藏，0未收藏
        Integer flag=userService.isCollect(userId,goodsId);

        data.put("userHasCollect",flag);

        data.put("specificationList", goodsSpecificationVOS);

        data.put("productList", goodsProducts);

        // 获取评论
        CommentDTO commentDTO = new CommentDTO();
        commentDTO.setValueId(goodsId.intValue());
        commentDTO.setCommentType(0);
        commentDTO.setSize(2);
        commentDTO.setCurrent(1);
        data.put("comment", commentService.listCommentByPage(commentDTO,0));

        return CommonResponse.success(data);
    }

    /**
     * 根据商品id查询评论
     * @return
     */
    public Object getComments(){
//        List<LitemallComment> comments = commentService.queryGoodsByGid(id, 0, 2);
//        List<Map<String, Object>> commentsVo = new ArrayList<>(comments.size());
//        long commentCount = PageInfo.of(comments).getTotal();
//        for (LitemallComment comment : comments) {
//            Map<String, Object> c = new HashMap<>();
//            c.put("id", comment.getId());
//            c.put("addTime", comment.getAddTime());
//            c.put("content", comment.getContent());
//            LitemallUser user = userService.findById(comment.getUserId());
//            c.put("nickname", user == null ? "" : user.getNickname());
//            c.put("avatar", user == null ? "" : user.getAvatar());
//            c.put("picList", comment.getPicUrls());
//            commentsVo.add(c);
//        }
//        Map<String, Object> commentList = new HashMap<>();
//        commentList.put("count", commentCount);
//        commentList.put("data", commentsVo);
//        return commentList;
        return null;

    }
    /**
     * 获取当前商品的规格并且封装
     * @param goodsId
     * @return
     */
     public List<GoodsSpecificationVO> getSpecification(Long goodsId){


         List<GoodsSpecificationVO> goodsSpecificationVOS=new ArrayList<>();
         //使用一个map记录保存状态
         Map<String,GoodsSpecificationVO> map=new HashMap<>();

         //1.规格表查出该商品的所有记录
         List<GoodsSpecification> goodsSpecifications=goodsSpecificationMapper.selectList(
                 new LambdaQueryWrapper<GoodsSpecification>().eq(GoodsSpecification::getGoodsId,goodsId));

         for (GoodsSpecification s:goodsSpecifications) {

             String name=s.getName();
             GoodsSpecificationVO flag=map.get(name);

             if(flag==null){
                 flag=new GoodsSpecificationVO();
                 flag.setName(name);
                 List<GoodsSpecification> temp=new ArrayList<>();
                 temp.add(s);
                 flag.setValueList(temp);

                 map.put(name,flag);
                 goodsSpecificationVOS.add(flag);
             }else {
                 flag.getValueList().add(s);
             }

         }
         return goodsSpecificationVOS;

    }

    /**
     * 根据二级分类id查询，父级分类和兄弟分类
     * @param id
     * @return
     */
    public CommonResponse category(Long id){

        //1.查找当前分类
        Category cur = categoryMapper.selectById(id);
        Category parent = null;
        List<Category> children = null;

        //2.如果是主页一级分类进来的pid就是0
        if (cur.getPid() == 0) {
            parent = cur;
            //查找一级分类的所有二级分类categorycategorycategory
            children = categoryMapper.selectList(new LambdaQueryWrapper<Category>().eq(Category::getPid,cur.getId()));
            cur = children.size() > 0 ? children.get(0) : cur;
        } else {
            //3.从分类页面进来的，点的是二级分类
            parent = categoryMapper.selectById(cur.getPid());
            children = categoryMapper.selectList(new LambdaQueryWrapper<Category>().eq(Category::getPid,cur.getPid()));
        }

        Map<String,Object> data=new HashMap<>();
        data.put("currentCategory", cur);
        data.put("parentCategory", parent);
        data.put("brotherCategory", children);
        return CommonResponse.success(data);
    }

    /**
     * 通过商品id查询相应的商品规格和商品库存
     * @param goodsId
     * @return
     */
    public CommonResponse standard(Long goodsId){

        //2.规格
        QueryWrapper queryWrapper=new QueryWrapper();
        queryWrapper.eq("goods_id",goodsId);
        Object[] specifications=goodsSpecificationMapper.selectList(queryWrapper).toArray();



        //3.产品
        List<GoodsProduct> goodsProducts=goodsProductMapper.selectList(queryWrapper);

        //转换
        GoodsProductVO[] goodsProductVOS=new GoodsProductVO[goodsProducts.size()];
        int index=0;

        for (GoodsProduct gp:goodsProducts) {

            GoodsProductVO temp=new GoodsProductVO();
            BeanUtils.copyProperties(gp,temp);
            String ss=gp.getSpecifications();
            temp.setSpecifications(ss.split(","));
            goodsProductVOS[index]=temp;
            index++;

        }


        Map<String,Object> map=new HashMap<>();
        map.put("specifications",specifications);
        map.put("productForm",goodsProductVOS);

        return CommonResponse.success(map);
    }
}
